home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1996 #15 / Monster Media Number 15 (Monster Media)(July 1996).ISO / bbs_util / bsrc_260.zip / SRC.ZIP / FILE_DOS.C < prev    next >
C/C++ Source or Header  |  1996-03-23  |  25KB  |  973 lines

  1. /*--------------------------------------------------------------------------*/
  2. /*                                                                          */
  3. /*                                                                          */
  4. /*      ------------         Bit-Bucket Software, Co.                       */
  5. /*      \ 10001101 /         Writers and Distributors of                    */
  6. /*       \ 011110 /          Freely Available<tm> Software.                 */
  7. /*        \ 1011 /                                                          */
  8. /*         ------                                                           */
  9. /*                                                                          */
  10. /*              (C) Copyright 1987-96, Bit Bucket Software Co.              */
  11. /*                                                                          */
  12. /*                This module was written by Vince Perriello                */
  13. /*                   OS/2 code contributed by Bill Andrus                   */
  14. /*            DOS and OS/2 File I/O routines used by BinkleyTerm            */
  15. /*                                                                          */
  16. /*                                                                          */
  17. /*    For complete  details  of the licensing restrictions, please refer    */
  18. /*    to the License  agreement,  which  is published in its entirety in    */
  19. /*    the MAKEFILE and BT.C, and also contained in the file LICENSE.260.    */
  20. /*                                                                          */
  21. /*    USE  OF THIS FILE IS SUBJECT TO THE  RESTRICTIONS CONTAINED IN THE    */
  22. /*    BINKLEYTERM  LICENSING  AGREEMENT.  IF YOU DO NOT FIND THE TEXT OF    */
  23. /*    THIS  AGREEMENT IN ANY OF THE  AFOREMENTIONED FILES,  OR IF YOU DO    */
  24. /*    NOT HAVE THESE FILES,  YOU  SHOULD  IMMEDIATELY CONTACT BIT BUCKET    */
  25. /*    SOFTWARE CO.  AT ONE OF THE  ADDRESSES  LISTED BELOW.  IN NO EVENT    */
  26. /*    SHOULD YOU  PROCEED TO USE THIS FILE  WITHOUT HAVING  ACCEPTED THE    */
  27. /*    TERMS  OF  THE  BINKLEYTERM  LICENSING  AGREEMENT,  OR  SUCH OTHER    */
  28. /*    AGREEMENT AS YOU ARE ABLE TO REACH WITH BIT BUCKET SOFTWARE, CO.      */
  29. /*                                                                          */
  30. /*                                                                          */
  31. /* You can contact Bit Bucket Software Co. at any one of the following      */
  32. /* addresses:                                                               */
  33. /*                                                                          */
  34. /* Bit Bucket Software Co.        FidoNet  1:104/501, 1:343/491             */
  35. /* P.O. Box 460398                AlterNet 7:42/1491                        */
  36. /* Aurora, CO 80046               BBS-Net  86:2030/1                        */
  37. /*                                Internet f491.n343.z1.fidonet.org         */
  38. /*                                                                          */
  39. /* Please feel free to contact us at any time to share your comments about  */
  40. /* our software and/or licensing policies.                                  */
  41. /*                                                                          */
  42. /*--------------------------------------------------------------------------*/
  43.  
  44. /* Include this file before any other includes or defines! */
  45.  
  46. #include "includes.h"
  47.  
  48. #ifdef NEED_MKTEMP
  49. char *
  50. mktemp (char *template)
  51. {
  52.     static char save[8] = "Z";
  53.     char *p;
  54.     int i;
  55.  
  56.     p = save;
  57.  
  58.     if (*p == 'Z')
  59.         sprintf (p, "%06d", TaskNumber);
  60.     while (*p)
  61.     {
  62.         if (isdigit (*p))
  63.         {
  64.             *p = 'a';
  65.             break;
  66.         }
  67.         if (*p++ < 'z')
  68.         {
  69.             break;
  70.         }
  71.     }
  72.     if ((*p == '\0') || ((i = strlen (template)) < 6))
  73.         return (NULL);
  74.     strcpy (&template[i - 6], save);
  75.     return (template);
  76. }
  77. #endif
  78.  
  79. #ifdef NEED_DOSREAD
  80. #ifdef _WIN32
  81. int 
  82. _dos_read (int fd, void far * buf, unsigned nbytes, unsigned int *bytes_read)
  83. {
  84.     *bytes_read = read (fd, buf, nbytes);
  85.     return (*bytes_read == nbytes) ? 0 : -1;
  86. }
  87.  
  88. int 
  89. _dos_write (int fd, void far * buf, unsigned nbytes, unsigned int *bytes_read)
  90. {
  91.     *bytes_read = write (fd, buf, nbytes);
  92.     return (*bytes_read == nbytes) ? 0 : -1;
  93. }
  94. #endif
  95. #ifdef DOS16
  96. int 
  97. _dos_read (int fd, void far * buf, unsigned nbytes, unsigned int *bytes_read)
  98. {
  99.     union REGS regs;
  100.     struct SREGS sregs;
  101.  
  102.     regs.h.ah = 0x3f;            /* read file */
  103.     regs.x.bx = fd;
  104.     regs.x.cx = nbytes;
  105.     regs.x.dx = FP_OFF (buf);
  106.     sregs.ds = FP_SEG (buf);
  107.     *bytes_read = intdosx (®s, ®s, &sregs);
  108.     return regs.x.cflag ? -1 : 0;
  109. }
  110.  
  111. int 
  112. _dos_write (int fd, void far * buf, unsigned nbytes, unsigned int *bytes_read)
  113. {
  114.     union REGS regs;
  115.     struct SREGS sregs;
  116.  
  117.     regs.h.ah = 0x40;            /* write file */
  118.     regs.x.bx = fd;
  119.     regs.x.cx = nbytes;
  120.     regs.x.dx = FP_OFF (buf);
  121.     sregs.ds = FP_SEG (buf);
  122.     *bytes_read = intdosx (®s, ®s, &sregs);
  123.     return regs.x.cflag ? -1 : 0;
  124. }
  125. #endif
  126. #endif
  127.  
  128. /* For Borland C++ 2.0, change __TURBOC_OLD__ to __TURBOC__ */
  129. #ifdef __TURBOC_OLD__
  130. /*
  131.  * utime function for Turbo / Borland C.
  132.  *
  133.  * We should make this more generic in case some other DOS
  134.  * compiler comes up lacking, but for now the only one we
  135.  * have that needs it happens to be Borland.
  136.  *
  137.  */
  138.  
  139. int cdecl 
  140. utime (char *name, struct utimbuf *times)
  141. {
  142.     int handle;
  143.     struct date d;
  144.     struct time t;
  145.     struct ftime ft;
  146.  
  147.     unixtodos (times->modtime, &d, &t);
  148.     ft.ft_tsec = t.ti_sec / 2;
  149.     ft.ft_min = t.ti_min;
  150.     ft.ft_hour = t.ti_hour;
  151.     ft.ft_day = d.da_day;
  152.     ft.ft_month = d.da_mon;
  153.     ft.ft_year = d.da_year - 1980;
  154.     if ((handle = open (name, O_RDONLY)) == -1)
  155.         return -1;
  156.  
  157.     setftime (handle, &ft);
  158.     close (handle);
  159.     return 0;
  160. }
  161. #endif
  162.  
  163. int 
  164. dexists (char *filename)
  165. {
  166.     struct stat stbuf;
  167.  
  168.     return (stat (filename, &stbuf) != -1) ? 1 : 0;
  169. }
  170.  
  171. int 
  172. got_error (char *string1, char *string2)
  173. {
  174.     if (errno == 0x18)
  175.         errno = 0;
  176.     if (errno != 0)
  177.     {
  178.         status_line ("%s %d, %s %s %s", MSG_TXT (M_ERROR), errno, MSG_TXT (M_CANT), string1, string2);
  179.         errno = 0;
  180.         return (1);
  181.     }
  182.     return (0);
  183. }
  184.  
  185. /* Z F R E E -- Return total number of free bytes on drive specified */
  186.  
  187. #ifdef DOS16
  188. long 
  189. zfree (char *drive)
  190. {
  191.     union REGS r;
  192.  
  193.     unsigned char driveno;
  194.     long stat;
  195.  
  196.     if (drive[0] != '\0' && drive[1] == ':')
  197.     {
  198.         driveno = (unsigned char) (islower (*drive) ? toupper (*drive) : *drive);
  199.         driveno = (unsigned char) (driveno - 'A' + 1);
  200.     }
  201.     else
  202.         driveno = 0;            /* Default drive    */
  203.  
  204.     r.x.ax = 0x3600;            /* get free space   */
  205.     r.h.dl = driveno;            /* on this drive    */
  206.     (void) int86 (0x21, &r, &r);/* go do it         */
  207.  
  208.     if (r.x.ax == 0xffff)        /* error return??   */
  209.         return (0);
  210.  
  211.     stat = (long) r.x.bx        /* bx = clusters avail  */
  212.         * (long) r.x.ax            /* ax = sectors/clust   */
  213.         * (long) r.x.cx;        /* cx = bytes/sector    */
  214.  
  215.     return (stat);
  216.  
  217. }
  218. #endif                            /* DOS16 */
  219.  
  220. #ifdef OS_2
  221. long 
  222. zfree (char *path)
  223. {
  224.     int drive;
  225.     FSALLOCATE dt;
  226.  
  227.     if (*path != '\0' && path[1] == ':')
  228.         drive = tolower (*path) - 'a' + 1;
  229.     else
  230.         drive = 0;
  231.     DosQFSInfo ((USHORT) drive, 1, (unsigned char far *) &dt, sizeof (FSALLOCATE));
  232.     return (dt.cSectorUnit * dt.cUnitAvail * dt.cbSector);
  233. }
  234. #endif
  235.  
  236. #ifdef _WIN32
  237. long 
  238. zfree (char *drive)
  239. {
  240.     unsigned driveno;
  241.     struct _diskfree_t diskinfo;
  242.     long stat;
  243.  
  244.     if (drive[0] != '\0' && drive[1] == ':')
  245.     {
  246.         driveno = (unsigned) (islower (*drive) ? toupper (*drive) : *drive);
  247.         driveno = (unsigned) (driveno - 'A' + 1);
  248.     }
  249.     else
  250.         driveno = 0;            /* Default drive    */
  251.  
  252.     if (_getdiskfree (driveno, &diskinfo) != 0)
  253.         return 0;
  254.  
  255.     stat = diskinfo.avail_clusters
  256.         * diskinfo.sectors_per_cluster
  257.         * diskinfo.bytes_per_sector;
  258.  
  259.     return (stat);
  260. }
  261. #endif                            /* _WIN32 */
  262.  
  263. static int share_flags[] =
  264. {
  265. #ifdef SH_COMPAT
  266.     SH_COMPAT,
  267. #else
  268.     0,
  269. #endif
  270.     SH_DENYNO,
  271.     SH_DENYRD,
  272.     SH_DENYRW,
  273.     SH_DENYWR
  274. };
  275.  
  276. int 
  277. share_open (char *filename, int oflag, int shflag)
  278. {
  279. #ifdef DOS16
  280.     if ((no_sharing == 0) && (_osmajor >= 3))
  281. #else
  282.     if (no_sharing == 0)
  283. #endif /* DOS16 */
  284.         return (sopen (filename, oflag, share_flags[shflag]));
  285.     else
  286.         return (open (filename, oflag));
  287.  
  288. }
  289.  
  290. FILE *
  291. share_fopen (char *filename, char *mode, int shflag)
  292. {
  293. #ifdef MUST_FDOPEN
  294.     int fd;
  295.     int open_mode;
  296.     char c, *p;
  297.     int sflag = S_IREAD | S_IWRITE;
  298.     FILE *stream;
  299.  
  300. /*
  301.  *  Microsoft made this easy for us. They gave us a stream-open
  302.  *  function that supports file sharing. Borland was not so kind.
  303.  *  So -- what we do here is open the file using the only sharing
  304.  *  API they provide -- that gives us a file handle -- then we
  305.  *  use fdopen to get a file stream out of it. Sheesh!
  306.  *
  307.  *  Of course, Microsoft 5.1 provides about the same level of
  308.  *  support as Borland -- almost. They explicitly warn you not
  309.  *  to do this neat thing I did for Borland. So I get no sharing
  310.  *  support for fopen() under 5.1. Double sheesh!
  311.  */
  312.     if ((no_sharing == 0) && (_osmajor >= 3))
  313.     {
  314.  
  315.         /* Figure out the translation from fopen-mode to
  316.            open-mode... */
  317.  
  318.         p = mode;
  319.         c = *p++;
  320.         if (c == 'w')
  321.             open_mode = O_CREAT | O_RDWR;
  322.         else if (c == 'r')
  323.             open_mode = O_RDONLY;
  324.         else if (c == 'a')
  325.             open_mode = O_CREAT | O_RDWR | O_APPEND;
  326.         else
  327.             return (FILE *) NULL;
  328.         while (*p)
  329.         {
  330.             c = *p++;
  331.             if (c == 't')
  332.                 open_mode = (open_mode & ~O_BINARY) | O_TEXT;
  333.             if (c == 'b')
  334.                 open_mode = (open_mode & ~O_TEXT) | O_BINARY;
  335.             if (c == '+')
  336.             {
  337.                 if ((open_mode & (O_RDONLY | O_WRONLY | O_RDWR)) == O_RDONLY)
  338.                 {
  339.                     open_mode = (open_mode & ~O_RDONLY) | O_RDWR;
  340.                 }
  341.                 else if (!(open_mode & O_APPEND))
  342.                     open_mode |= O_TRUNC;
  343.             }
  344.         }
  345.  
  346.         /* Open the file handle */
  347.  
  348. #ifdef    SHARE_SOPEN
  349.         fd = sopen (filename, open_mode, share_flags[shflag], sflag);
  350. #else
  351.         fd = open (filename, open_mode | share_flags[shflag], sflag);
  352. #endif
  353.         if (fd == -1)
  354.             return (FILE *) NULL;
  355.  
  356.         /* Got the handle, make the stream */
  357.  
  358.         if ((stream = fdopen (fd, mode)) == (FILE *) NULL)
  359.             (void) close (fd);
  360.         return (stream);
  361.     }
  362.     else
  363. #else
  364. #ifndef CANT_FSOPEN
  365. #ifdef DOS16
  366.     if ((no_sharing == 0) && (_osmajor >= 3))
  367. #else
  368.     if (no_sharing == 0)
  369. #endif /* DOS16 */
  370.         return (_fsopen (filename, mode, share_flags[shflag]));
  371.     else
  372. #else
  373.     happy_compiler = shflag;    /* Makes the compiler happy */
  374. #endif
  375. #endif
  376.     return (fopen (filename, mode));
  377. }
  378.  
  379. #ifdef DOS16
  380. int 
  381. dfind (struct FILEINFO *dta, char *name, int times)
  382. {
  383.     union REGS r;
  384.     struct SREGS s;
  385.     char far *dtaptr = (char *) dta;
  386.     char far *nameptr = (char *) name;
  387.  
  388.     s.ds = FP_SEG (dtaptr);
  389.     r.x.dx = FP_OFF (dtaptr);
  390.     r.h.ah = 0x1a;
  391.     (void) intdosx (&r, &r, &s);
  392.     r.x.bx = 0;
  393.     r.x.cx = (unsigned int) ~0x08;
  394.     s.ds = FP_SEG (nameptr);
  395.     r.x.dx = FP_OFF (nameptr);
  396.     r.x.si = 0;
  397.     r.x.di = 0;
  398.     if (times == 0)
  399.     {
  400.         r.h.ah = 0x4e;
  401.         (void) intdosx (&r, &r, &s);
  402.         dta->nill = '\0';
  403.         /* If not found or a character device (e.g. "COM1") */
  404.         if ((r.x.cflag != 0) || ((dta->attr & 0x40) != 0))
  405.         {
  406.             dta->name[0] = '\0';
  407.             return (1);
  408.         }
  409.         return (0);
  410.     }
  411.     else if (times == 1)
  412.     {
  413.         r.h.ah = 0x4f;
  414.         (void) intdosx (&r, &r, &s);
  415.         dta->nill = '\0';
  416.         /* If not found or a character device (e.g. "COM1") */
  417.         if ((r.x.cflag != 0) || ((dta->attr & 0x40) != 0))
  418.         {
  419.             dta->name[0] = '\0';
  420.             return (1);
  421.         }
  422.         return (0);
  423.     }
  424.     else
  425.         return (0);
  426. }
  427.  
  428. #endif                            /* DOS16 */
  429.  
  430. #ifdef OS_2
  431. #ifndef __32BIT__
  432.  
  433. static int dir_findfirst (char far *, int, struct FILEINFO *);
  434. static int dir_findnext (struct FILEINFO *);
  435. static int dir_findrelease (struct FILEINFO *);
  436.  
  437. int 
  438. dfind (struct FILEINFO *dta, char *name, int times)
  439. {
  440.     if (times == 0)
  441.     {
  442.         return (dir_findfirst (name, 0x37, dta));
  443.     }
  444.     else if (times == 1)
  445.     {
  446.         return (dir_findnext (dta));
  447.     }
  448.     else
  449.         return (dir_findrelease (dta));
  450. }
  451.  
  452. /*--------------------------------------------------------------------------*/
  453. /* Static variable definitions                                              */
  454. /*--------------------------------------------------------------------------*/
  455.  
  456. struct FileTimeBuf
  457. {
  458.     unsigned short c_date;        /* date of file creation */
  459.     unsigned short c_time;        /* time of file creation */
  460.     unsigned short a_date;        /* date of last access   */
  461.     unsigned short a_time;        /* time of last access   */
  462.     unsigned short w_date;        /* date of last write    */
  463.     unsigned short w_time;        /* time of last write    */
  464. };
  465.  
  466. static struct FileTimeBuf TimeBuf;
  467.  
  468. struct FileInfo
  469. {
  470.     USHORT hDir;
  471.     char rsvd[19];
  472.     char attrib;
  473.     unsigned short wr_date;
  474.     unsigned short wr_time;
  475.     long size;
  476.     char name[13];
  477.     char nill;
  478. };
  479.  
  480. struct FileFindBuf
  481. {
  482.     unsigned short create_date;    /* date of file creation */
  483.     unsigned short create_time;    /* time of file creation */
  484.     unsigned short access_date;    /* date of last access */
  485.     unsigned short access_time;    /* time of last access */
  486.     unsigned short wr_date;        /* date of last write */
  487.     unsigned short wr_time;        /* time of last write */
  488.     unsigned long size;            /* file size (end of data) */
  489.     unsigned long falloc_size;    /* file allocated size */
  490.     unsigned short attrib;        /* attributes of the file */
  491.     unsigned char string_len;    /* returned length of ascii name str. */
  492.     /* length does not include null byte */
  493.     char name[255];                /* name string */
  494. };
  495.  
  496. static struct FileFindBuf InfoBuf;
  497.  
  498. /*--------------------------------------------------------------------------*/
  499. /* Locally defined globals                                                  */
  500. /*--------------------------------------------------------------------------*/
  501.  
  502. struct FileInfo *dtap;
  503. HDIR hDirA;
  504. USHORT cSearch;
  505. USHORT usAttrib;
  506. USHORT findrc;
  507.  
  508. /*--------------------------------------------------------------------------*/
  509. /* Local constants                                                          */
  510. /*--------------------------------------------------------------------------*/
  511.  
  512. #define FILENAMELEN 13
  513.  
  514. static int 
  515. dir_findfirst (char far * filename, int attribute, struct FILEINFO *dta)
  516. {
  517.  
  518.     cSearch = 1;
  519.     dtap = (struct FileInfo *) dta;
  520.     hDirA = dtap->hDir;
  521.     usAttrib = (USHORT) attribute;
  522.  
  523.     if ((hDirA != 0xffff) && (hDirA != 0x0000))
  524.         (void) DosFindClose (hDirA);
  525.  
  526.     hDirA = 0xffff;
  527.  
  528.     findrc = DosFindFirst ((PSZ) filename
  529.         ,&hDirA
  530.         ,usAttrib
  531.         ,(PFILEFINDBUF) & InfoBuf
  532.         ,(USHORT)(sizeof (InfoBuf)) * cSearch
  533.         ,&cSearch
  534.         ,(ULONG) NULL);
  535.     if ((cSearch != 1) || (findrc && (findrc != ERROR_EAS_DIDNT_FIT)))
  536.     {
  537.         (void) DosFindClose (hDirA);
  538.         dtap->hDir = 0xffff;
  539.         errno = ENOENT;
  540.         return (1);
  541.     }
  542.     else
  543.     {
  544.         dtap->wr_date = InfoBuf.wr_date;
  545.         dtap->wr_time = InfoBuf.wr_time;
  546.         dtap->attrib = (char) InfoBuf.attrib;
  547.         dtap->size = InfoBuf.size / ((_osmajor == 10) ? 2 : 1);
  548.         strcpy (dtap->name, InfoBuf.name);
  549.         (void) strupr (dtap->name);
  550.         dtap->hDir = hDirA;
  551.         errno = 0;
  552.         return (0);
  553.     }
  554. }
  555.  
  556. static int 
  557. dir_findnext (struct FILEINFO *dta)
  558. {
  559.  
  560.     cSearch = 1;
  561.     dtap = (struct FileInfo *) dta;
  562.     hDirA = dtap->hDir;
  563.  
  564.     findrc = DosFindNext (hDirA
  565.         ,(PFILEFINDBUF) & InfoBuf
  566.         ,(USHORT) (sizeof (InfoBuf)) * cSearch
  567.         ,&cSearch);
  568.  
  569.     if ((cSearch != 1) || (findrc && (findrc != ERROR_EAS_DIDNT_FIT)))
  570.     {
  571.         (void) DosFindClose (hDirA);
  572.         dtap->hDir = 0xffff;
  573.         errno = ENOENT;
  574.         return (1);
  575.     }
  576.     else
  577.     {
  578.         dtap->wr_date = InfoBuf.wr_date;
  579.         dtap->wr_time = InfoBuf.wr_time;
  580.         dtap->attrib = (char) InfoBuf.attrib;
  581.         dtap->size = InfoBuf.size / ((_osmajor == 10) ? 2 : 1);
  582.         strcpy (dtap->name, InfoBuf.name);
  583.         (void) strupr (dtap->name);
  584.         dtap->hDir = hDirA;
  585.         errno = 0;
  586.         return (0);
  587.     }
  588. }
  589.  
  590. static int 
  591. dir_findrelease (struct FILEINFO *dta)
  592. {
  593.     dtap = (struct FileInfo *) dta;
  594.     hDirA = dtap->hDir;
  595.  
  596.     if (hDirA != 0xffff)
  597.     {
  598.         (void) DosFindClose (hDirA);
  599.         dtap->hDir = 0xffff;
  600.         errno = ENOENT;
  601.         return (1);
  602.     }
  603.     else
  604.         return (0);
  605. }
  606.  
  607. void 
  608. set_fileinfo (int fh, unsigned date, unsigned time)
  609. {
  610.  
  611.     if ((time / 2048) < (unsigned) (TIMEZONE / 3600L))
  612.     {
  613.         TimeBuf.a_date = TimeBuf.w_date = TimeBuf.c_date = date - 1;
  614.         TimeBuf.c_time = time + ((unsigned) (86400 - ((unsigned) (TIMEZONE / 3600L) * 2048)));
  615.         TimeBuf.a_time = TimeBuf.w_time = TimeBuf.c_time;
  616.     }
  617.     else
  618.     {
  619.         TimeBuf.a_date = TimeBuf.w_date = TimeBuf.c_date = date;
  620.         TimeBuf.c_time = time - ((unsigned) (TIMEZONE / 3600L) * 2048);
  621.         TimeBuf.a_time = TimeBuf.w_time = TimeBuf.c_time;
  622.     }
  623.     (void) DosSetFileInfo ((HFILE) fh,
  624.         (USHORT) 1,
  625.         (PBYTE) & TimeBuf,
  626.         (USHORT) 12);
  627. }
  628.  
  629. #else                            /* ifndef __32BIT__ */
  630.  
  631. static int dir_findfirst (char far *, int, struct FILEINFO *);
  632. static int dir_findnext (struct FILEINFO *);
  633. static int dir_findrelease (struct FILEINFO *);
  634.  
  635. int 
  636. dfind (struct FILEINFO *dta, char *name, int times)
  637. {
  638.     if (times == 0)
  639.     {
  640.         return (dir_findfirst (name, 0x37, dta));
  641.     }
  642.     else if (times == 1)
  643.     {
  644.         return (dir_findnext (dta));
  645.     }
  646.     else
  647.         return (dir_findrelease (dta));
  648. }
  649.  
  650. /*--------------------------------------------------------------------------*/
  651. /* Static variable definitions                                              */
  652. /*--------------------------------------------------------------------------*/
  653.  
  654. struct FileTimeBuf
  655. {
  656.     unsigned short c_date;        /* date of file creation */
  657.     unsigned short c_time;        /* time of file creation */
  658.     unsigned short a_date;        /* date of last access   */
  659.     unsigned short a_time;        /* time of last access   */
  660.     unsigned short w_date;        /* date of last write    */
  661.     unsigned short w_time;        /* time of last write    */
  662. };
  663.  
  664. static struct FileTimeBuf TimeBuf;
  665.  
  666. struct FileInfo
  667. {
  668.     unsigned short hDir;
  669.     char rsvd[19];
  670.     char attrib;
  671.     unsigned short wr_date;
  672.     unsigned short wr_time;
  673.     ULONG size;
  674.     char name[13];
  675.     char nill;
  676. };
  677.  
  678. struct FileFindBuf
  679. {
  680.     ULONG nDir;                    /* pointer to next structure */
  681.     unsigned short create_date;    /* date of file creation */
  682.     unsigned short create_time;    /* time of file creation */
  683.     unsigned short access_date;    /* date of last access */
  684.     unsigned short access_time;    /* time of last access */
  685.     unsigned short wr_date;        /* date of last write */
  686.     unsigned short wr_time;        /* time of last write */
  687.     ULONG size;                    /* file size (end of data) */
  688.     ULONG falloc_size;            /* file allocated size */
  689.     ULONG attrib;                /* attributes of the file */
  690.     UCHAR string_len;            /* returned length of ascii name str. */
  691.     /* length does not include null byte */
  692.     char name[CCHMAXPATHCOMP];    /* name string */
  693. };
  694.  
  695. static struct FileFindBuf InfoBuf;
  696.  
  697. /*--------------------------------------------------------------------------*/
  698. /* Locally defined globals                                                  */
  699. /*--------------------------------------------------------------------------*/
  700.  
  701. struct FileInfo *dtap;
  702. HDIR hDirA;
  703. ULONG cSearch;
  704. ULONG usAttrib;
  705. ULONG infolevel;
  706. APIRET findrc;
  707.  
  708. /*--------------------------------------------------------------------------*/
  709. /* Local constants                                                          */
  710. /*--------------------------------------------------------------------------*/
  711.  
  712. #define FILENAMELEN 13
  713.  
  714. static int 
  715. dir_findfirst (char far * filename, int attribute, struct FILEINFO *dta)
  716. {
  717.  
  718.     cSearch = 1;
  719.     dtap = (struct FileInfo *) dta;
  720.     hDirA = dtap->hDir;
  721.     usAttrib = (USHORT) attribute;
  722.     infolevel = 1;
  723.  
  724.     if ((hDirA != 0xffff) && (hDirA != 0x0000) && (hDirA != 0xffffffff))
  725.         (void) DosFindClose (hDirA);
  726.  
  727.     hDirA = 0xffffffff;
  728.  
  729.     findrc = DosFindFirst ((PSZ) filename
  730.         ,&hDirA
  731.         ,usAttrib
  732.         ,(PVOID) & InfoBuf
  733.         ,(ULONG) (sizeof (InfoBuf) * cSearch)
  734.         ,&cSearch
  735.         ,infolevel);
  736.  
  737.     if ((cSearch != 1) || (findrc && (findrc != ERROR_EAS_DIDNT_FIT)))
  738.     {
  739.         (void) DosFindClose (hDirA);
  740.         dtap->hDir = 0xffff;
  741.         errno = ENOENT;
  742.         return (1);
  743.     }
  744.     else
  745.     {
  746.         dtap->wr_date = InfoBuf.wr_date;
  747.         dtap->wr_time = InfoBuf.wr_time;
  748.         dtap->attrib = (char) InfoBuf.attrib;
  749.         dtap->size = InfoBuf.size / ((_osmajor == 10) ? 2 : 1);
  750.         strcpy (dtap->name, InfoBuf.name);
  751.         (void) strupr (dtap->name);
  752.         dtap->hDir = hDirA;
  753.         errno = 0;
  754.         return (0);
  755.     }
  756. }
  757.  
  758. static int 
  759. dir_findnext (struct FILEINFO *dta)
  760. {
  761.  
  762.     cSearch = 1;
  763.     dtap = (struct FileInfo *) dta;
  764.     hDirA = dtap->hDir;
  765.  
  766.     findrc = DosFindNext (hDirA
  767.         ,(PVOID) & InfoBuf
  768.         ,(ULONG) (sizeof (InfoBuf) * cSearch)
  769.         ,&cSearch);
  770.  
  771.     if ((cSearch != 1) || (findrc && (findrc != ERROR_EAS_DIDNT_FIT)))
  772.     {
  773.         (void) DosFindClose (hDirA);
  774.         dtap->hDir = 0xffff;
  775.         errno = ENOENT;
  776.         return (1);
  777.     }
  778.     else
  779.     {
  780.         dtap->wr_date = InfoBuf.wr_date;
  781.         dtap->wr_time = InfoBuf.wr_time;
  782.         dtap->attrib = (char) InfoBuf.attrib;
  783.         dtap->size = InfoBuf.size / ((_osmajor == 10) ? 2 : 1);
  784.         strcpy (dtap->name, InfoBuf.name);
  785.         (void) strupr (dtap->name);
  786.         dtap->hDir = hDirA;
  787.         errno = 0;
  788.         return (0);
  789.     }
  790. }
  791.  
  792. static int 
  793. dir_findrelease (struct FILEINFO *dta)
  794. {
  795.     dtap = (struct FileInfo *) dta;
  796.     hDirA = dtap->hDir;
  797.  
  798.     if ((hDirA != 0xffff) && (hDirA != 0xffffffff))
  799.     {
  800.         (void) DosFindClose (hDirA);
  801.         dtap->hDir = 0xffff;
  802.         errno = ENOENT;
  803.         return (1);
  804.     }
  805.     else
  806.         return (0);
  807. }
  808.  
  809. void 
  810. set_fileinfo (int fh, unsigned date, unsigned time)
  811. {
  812.  
  813.     if ((time / 2048) < (unsigned) (TIMEZONE / 3600L))
  814.     {
  815.         TimeBuf.a_date = TimeBuf.w_date = TimeBuf.c_date = date - 1;
  816.         TimeBuf.c_time = time + ((unsigned) (86400 - ((unsigned) (TIMEZONE / 3600L) * 2048)));
  817.         TimeBuf.a_time = TimeBuf.w_time = TimeBuf.c_time;
  818.     }
  819.     else
  820.     {
  821.         TimeBuf.a_date = TimeBuf.w_date = TimeBuf.c_date = date;
  822.         TimeBuf.c_time = time - ((unsigned) (TIMEZONE / 3600L) * 2048);
  823.         TimeBuf.a_time = TimeBuf.w_time = TimeBuf.c_time;
  824.     }
  825.     (void) DosSetFileInfo ((HFILE) fh,
  826.         (USHORT) 1,
  827.         (PBYTE) & TimeBuf,
  828.         (USHORT) 12);
  829. }
  830.  
  831. #endif                            /* ifndef __32BIT__ */
  832. #endif                            /* ifdef OS_2 */
  833.  
  834. #ifdef _WIN32
  835. static int dir_findfirst (char far *, struct FILEINFO *);
  836. static int dir_findnext (struct FILEINFO *);
  837. static int dir_findrelease (struct FILEINFO *);
  838.  
  839. int 
  840. dfind (struct FILEINFO *dta, char *name, int times)
  841. {
  842.     if (times == 0)
  843.     {
  844.         return (dir_findfirst (name, dta));
  845.     }
  846.     else if (times == 1)
  847.     {
  848.         return (dir_findnext (dta));
  849.     }
  850.     else
  851.         return (dir_findrelease (dta));
  852. }
  853.  
  854. /*--------------------------------------------------------------------------*/
  855. /* Static variable definitions                                              */
  856. /*--------------------------------------------------------------------------*/
  857.  
  858. struct FileInfo
  859. {
  860.     long hDir;
  861.     int fActive;
  862.     char rsvd[13];
  863.     char attrib;
  864.     long time;
  865.     long size;
  866.     char name[13];
  867.     char nill;
  868. };
  869.  
  870. static struct _finddata_t InfoBuf;
  871.  
  872. /*--------------------------------------------------------------------------*/
  873. /* Local functions                                                          */
  874. /*--------------------------------------------------------------------------*/
  875.  
  876. static void dir_move (struct FileInfo *dta);
  877.  
  878. /*--------------------------------------------------------------------------*/
  879. /* Local constants                                                          */
  880. /*--------------------------------------------------------------------------*/
  881.  
  882. #define FILENAMELEN 13
  883.  
  884. static int 
  885. dir_findfirst (char far * filename, struct FILEINFO *dta)
  886. {
  887.     struct FileInfo *dtap = (struct FileInfo *) dta;
  888.     long hDirA;
  889.  
  890.     if (dtap->fActive)
  891.     {
  892.         (void) dir_findrelease (dta);
  893.     }
  894.  
  895.     hDirA = _findfirst (filename, &InfoBuf);
  896.  
  897.     if (hDirA == -1)
  898.     {
  899.         errno = ENOENT;
  900.         return (1);
  901.     }
  902.  
  903.     dir_move (dtap);
  904.     dtap->hDir = hDirA;
  905.     dtap->fActive = 1;
  906.     return (0);
  907. }
  908.  
  909. static int 
  910. dir_findnext (struct FILEINFO *dta)
  911. {
  912.     struct FileInfo *dtap = (struct FileInfo *) dta;
  913.     long hDirA;
  914.     int fResult;
  915.  
  916.     if (!dtap->fActive)
  917.         return (1);
  918.  
  919.     hDirA = dtap->hDir;
  920.  
  921.     fResult = (_findnext (hDirA, &InfoBuf) != 0);
  922.  
  923.     if (fResult)
  924.     {
  925.         errno = ENOENT;
  926.         (void) dir_findrelease (dta);
  927.         return (1);
  928.     }
  929.  
  930.     dir_move (dtap);
  931.     return (0);
  932. }
  933.  
  934. static void 
  935. dir_move (struct FileInfo *dtap)
  936. {
  937.     struct tm *ptm;
  938.     long timelong;
  939.  
  940.     ptm = localtime (&InfoBuf.time_write);
  941.     timelong =    (long) (ptm->tm_sec / 2)            +
  942.                 (long) ((ptm->tm_min)         << 5)    +
  943.                 (long) ((ptm->tm_hour)         << 11)    +
  944.                 (long) ((ptm->tm_mday)        << 16)    +
  945.                 (long) ((ptm->tm_mon + 1)    << 21)    +
  946.                 (long) ((ptm->tm_year - 80)    << 25);
  947.  
  948.     dtap->time = timelong;
  949.     dtap->size = InfoBuf.size;
  950.     dtap->attrib = (char) InfoBuf.attrib;
  951.     strncpy (dtap->name, InfoBuf.name, FILENAMELEN);
  952.     (void) strupr (dtap->name);
  953.     dtap->nill = 0;
  954.     errno = 0;
  955. }
  956.  
  957. static int 
  958. dir_findrelease (struct FILEINFO *dta)
  959. {
  960.     struct FileInfo *dtap = (struct FileInfo *) dta;
  961.     long hDirA;
  962.  
  963.     if (!dtap->fActive)
  964.         return (1);
  965.  
  966.     hDirA = dtap->hDir;
  967.  
  968.     (void) _findclose (hDirA);
  969.     dtap->fActive = 0;
  970.     return (0);
  971. }
  972. #endif                            /* ifdef _WIN32 */
  973.